package com.grm.sys.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.grm.common.Result;
import com.grm.exception.BusinessException;
import com.grm.sys.entity.SysUser;
import com.grm.sys.entity.SysUserRole;
import com.grm.sys.service.SysUserRoleService;
import com.grm.sys.service.SysUserService;
import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 系统用户控制器
 *
 * @author gaorimao
 * @date 2022/06/24
 */
@Slf4j
@RestController
@RequestMapping("/sys/user")
public class SysUserController {
    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Value("${password.secret}")
    private String secret;

    /**
     * 插入系统用户
     *
     * @param sysUser 系统用户
     * @return {@link Result}
     */
    @PreAuthorize("hasAuthority('sys:user:add')")
    @PostMapping("/add")
    public Result insert(@RequestBody SysUser sysUser) throws BusinessException{
        // 1.查询用户是否存在
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", sysUser.getUsername());
        SysUser dbSysUser = sysUserService.getOne(queryWrapper);
        if (dbSysUser != null) {
            throw new BusinessException(500, "用户已存在，不能重复添加！");
        }
        // 2.用户不存在时，可添加用户
        // 创建时间
        sysUser.setCreated(new Date());
        // 加密
        sysUser.setPassword(new BCryptPasswordEncoder().encode(sysUser.getPassword() + secret));
        sysUserService.save(sysUser);
        return Result.success("添加系统用户成功！");
    }

    /**
     * 删除系统用户
     *
     * @param id 系统用户id
     * @return {@link Result}
     */
    @PreAuthorize("hasAuthority('sys:user:delete')")
    @Transactional(rollbackFor = Exception.class)
    @DeleteMapping("/delete/{id}")
    public Result delete(@PathVariable Long id) {
        // 删除用户
        sysUserService.removeById(id);

        // 删除用户角色关联关系
        QueryWrapper<SysUserRole> sysUserRoleQueryWrapper = new QueryWrapper<>();
        sysUserRoleQueryWrapper.eq("user_id", id);
        sysUserRoleService.remove(sysUserRoleQueryWrapper);

        return Result.success("删除系统用户成功！");
    }

    /**
     * 批量删除系统用户
     *
     * @param sysUsers 系统用户s
     * @return {@link Result}
     */
    @PreAuthorize("hasAuthority('sys:user:batch:delete')")
    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/batch/delete")
    public Result batchDelete(@RequestBody List<SysUser> sysUsers) {
        List<Long> userIds = sysUsers.stream().map(SysUser::getId).collect(Collectors.toList());
        sysUserService.removeBatchByIds(userIds);

        // 删除用户角色关联关系
        QueryWrapper<SysUserRole> sysUserRoleQueryWrapper = new QueryWrapper<>();
        sysUserRoleQueryWrapper.in("user_id", userIds);
        sysUserRoleService.remove(sysUserRoleQueryWrapper);
        return Result.success("批量删除系统用户成功！");
    }

    /**
     * 修改系统用户
     *
     * @param sysUser 系统用户
     * @return {@link Result}
     */
    @PreAuthorize("hasAuthority('sys:user:update')")
    @PutMapping("/update")
    public Result update(@RequestBody SysUser sysUser) {
        // 修改时间
        sysUser.setUpdated(new Date());
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("id", sysUser.getId());
        sysUserService.update(sysUser, wrapper);
        return Result.success("修改系统用户成功！");
    }

    /**
     * 条件查询，带分页
     *
     * @param pageNum  页码
     * @param pageSize 页大小
     * @param sysUser  系统用户
     * @return {@link Result}
     */
    @PreAuthorize("hasAuthority('sys:user:list')")
    @PostMapping("/query/selective")
    public Result querySelective(@RequestParam Integer pageNum, @RequestParam Integer pageSize, @RequestBody SysUser sysUser) {
        //使用分页插件
        PageHelper.startPage(pageNum, pageSize);
        // 查询条件
        QueryWrapper<SysUser> wrapper = getQueryWrapper(sysUser);
        List<SysUser> sysUserList = sysUserService.list(wrapper);
        //获取总数
        PageInfo<SysUser> pageInfo = new PageInfo<>(sysUserList);
        Long total = pageInfo.getTotal();
        return Result.success("查询系统用户列表成功！", sysUserList, total);
    }

    /**
     * 查询所有用户
     *
     * @return {@link Result}
     */
    @GetMapping("/queryUserOptions")
    public Result queryUserOptions() {
        // 查询条件
        List<Map<String, String>> sysUserList = sysUserService.queryUserOptions();
        return Result.success("查询系统用户列表成功！", sysUserList);
    }

    /**
     * 给用户分配角色
     *
     * @param userId     分配角色的用户id
     * @param sysRoleIds 选定的角色ids
     * @return {@link Result}
     */
    @PreAuthorize("hasAuthority('sys:user:giveRoles')")
    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/giveRoles")
    public Result giveRoles(@RequestParam Long userId, @RequestBody List<Long> sysRoleIds) {
        // 删除用户&角色关联关系
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        sysUserRoleService.remove(queryWrapper);
        // 添加用户角色关联关系
        List<SysUserRole> sysUserRoles = new ArrayList<>();
        sysRoleIds.stream().forEach(sysRoleId -> {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(userId);
            sysUserRole.setRoleId(sysRoleId);
            sysUserRoles.add(sysUserRole);
        });
        sysUserRoleService.saveBatch(sysUserRoles);
        return Result.success("分配角色成功！");
    }

    @PostMapping("/rePassword")
    public Result rePassword(@RequestParam String username, @RequestBody Map<String, String> reqMap) throws BusinessException{
        QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
        sysUserQueryWrapper.eq("username", username);
        SysUser dbSysUser = sysUserService.getOne(sysUserQueryWrapper);
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        // 加密后的密码
        String dbPassword = dbSysUser.getPassword();
        boolean isMatch = encoder.matches(reqMap.get("oldPassword") + secret, dbPassword);
        if (!isMatch) {
            throw new BusinessException(500, "输入的旧密码错误！");
        }
        if (!reqMap.get("newPassword").equals(reqMap.get("rePassword"))) {
            throw new BusinessException(500, "两次输入的密码不一致！");
        }
        // 修改密码
        dbSysUser.setPassword(encoder.encode(reqMap.get("newPassword") + secret));
        sysUserService.updateById(dbSysUser);
        return Result.success("修改密码成功");
    }

    @GetMapping("/query/personalInfo")
    public Result queryPersonalInfo(@RequestParam String username) {
        return sysUserService.queryPersonalInfo(username);
    }

    /**
     * 封装查询条件的方法
     *
     * @param sysUser 系统用户
     * @return {@link QueryWrapper}<{@link SysUser}>
     */
    private QueryWrapper<SysUser> getQueryWrapper(SysUser sysUser) {
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        if (!ObjectUtils.isEmpty(sysUser.getUsername())) {
            wrapper.like("username", sysUser.getUsername());
        }
        if (!ObjectUtils.isEmpty(sysUser.getSex())) {
            wrapper.eq("sex", sysUser.getSex());
        }
        if (!ObjectUtils.isEmpty(sysUser.getPhone())) {
            wrapper.like("phone", sysUser.getPhone());
        }
        if (!ObjectUtils.isEmpty(sysUser.getEmail())) {
            wrapper.like("email", sysUser.getEmail());
        }
        wrapper.orderByDesc("created");
        return wrapper;
    }
}
